package net.ib.mtalk.ui.attachment.vcard.account;

import java.util.ArrayList;
import java.util.HashMap;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AuthenticatorDescription;
import android.content.Context;
import android.content.SyncAdapterType;
import android.provider.ContactsContract;

public class AccountMgr {
	
	public static AccountMgr instance;
	
	private HashMap<String, AccountSource> mSources = new HashMap<String, AccountSource>();
	
	public static AccountManager am;
	public static synchronized AccountMgr getInstance(Context context) {
		
		if (instance == null) {
			am = AccountManager.get(context);
			instance = new AccountMgr(context);
		}
		return instance;
	}
	
	private AccountMgr(Context context) {
		
		mSources.clear();
		
		final SyncAdapterType[] syncs = context.getContentResolver().getSyncAdapterTypes();
		final AuthenticatorDescription[] auths = am.getAuthenticatorTypes(); 
		
		for (SyncAdapterType sync : syncs) {

			if (!ContactsContract.AUTHORITY.equals(sync.authority)) continue;
			
			final String accountType = sync.accountType;
			final AuthenticatorDescription auth = findAuthenticator(auths, accountType);
			
			if (auth == null) continue;
			
			AccountSource data = new AccountSource(auth.packageName);
			
			data.accountType = auth.type;
			data.titleRes = auth.labelId;
			data.iconRes = auth.iconId;
			data.readOnly = !sync.supportsUploading();
			
			addSource(data);
		}
	}
	
	protected void addSource(AccountSource data) {
		mSources.put(data.accountType, data);
	}
	
	public ArrayList<AccountData> getAccountsData(Context context, boolean writableOnly) {
		final Account[] accounts = am.getAccounts();
		final ArrayList<AccountData> accountList = new ArrayList<AccountData>();
		
		for (Account account : accounts) {			
			final AccountSource source = mSources.get(account.type);
			if (source == null) continue;
			
			final boolean matcheswritable = (!writableOnly || (writableOnly && !source.readOnly));
			
			AccountData data = new AccountData(context, account.name, 
											source.accountType, source.resPackageName, 
											source.titleRes, source.iconRes);
			if (matcheswritable) {
				accountList.add(data);
			}
			
		}
		return accountList;
	}
	
	public ArrayList<Account> getAccounts(boolean writableOnly) {		
		final Account[] accounts = am.getAccounts();
		final ArrayList<Account> accountList = new ArrayList<Account>();
		
		for (Account account : accounts) {
			final AccountSource source = mSources.get(account.type);
			if (source == null) continue;
			
			final boolean matcheswritable = (!writableOnly || (writableOnly && !source.readOnly));
						
			if (matcheswritable) {
				accountList.add(account);
			}
		}
		return accountList;
	}
	
	private static AuthenticatorDescription findAuthenticator (AuthenticatorDescription[] auths, String accountType) {
		for (AuthenticatorDescription auth : auths) {
			if (accountType.equals(auth.type)) {
				return auth;
			}
		}
		return null;
	}
}
